package com.rh.number.service.impl;

import com.rh.number.entity.UserinfoEntity;
import com.rh.number.enums.SystemRole;
import com.rh.number.enums.UserRole;
import com.rh.number.exception.PermissionDeniedException;
import com.rh.number.exception.SelfRoleModificationException;
import com.rh.number.exception.UserNotFoundException;
import com.rh.number.exception.UseridNotFoundException;
import com.rh.number.mapper.UserinfoMapper;
import com.rh.number.service.AuthService;
import com.rh.number.util.JwtUtil;
import org.apache.tomcat.websocket.AuthenticationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Service
public class AuthServiceImpl implements AuthService {
    private final UserinfoMapper userMapper;
    private final BCryptPasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;

    @Autowired
    public AuthServiceImpl (UserinfoMapper userMapper, JwtUtil jwtUtil) {
        this.userMapper = userMapper;
        this.passwordEncoder = new BCryptPasswordEncoder();
        this.jwtUtil = jwtUtil;
    }

    @Override
    public String login(String username, String password) {
        UserinfoEntity user = userMapper.selectByUsername(username);
        if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        return jwtUtil.generateToken(user);
    }

    @Override
    public void addUser(UserinfoEntity user) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();


        // 1. 类型检查与转换
        if (!(authentication.getDetails() instanceof Map)) {
            throw new RuntimeException("认证信息格式异常");
        }

        @SuppressWarnings("unchecked")
        Map<String, Object> details = (Map<String, Object>) authentication.getDetails();

        // 2. 安全获取角色值
        Object roleObj = details.get("role");
        if (roleObj == null) {
            throw new RuntimeException("用户角色未定义");
        }

        Integer currentUserRole;
        try {
            currentUserRole = (Integer) roleObj;
        } catch (ClassCastException e) {
            throw new RuntimeException("角色类型不合法", e);
        }

        // 3. 权限校验逻辑
        UserRole currentRole = UserRole.fromCode(currentUserRole);
        if (currentRole != UserRole.ADMIN) {
            throw new RuntimeException("权限不足，需要管理员权限，当前角色：" + currentRole.getDesc());
        }
        UserinfoEntity existingUser = userMapper.selectByUsername(user.getUsername());
        if (existingUser != null) {
            throw new RuntimeException("用户已存在，用户名：" + user.getUsername());
        }

        // 4. 业务操作
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userMapper.insert(user);
    }

    public UserinfoEntity authenticate(String username, String password) throws AuthenticationException {
        UserinfoEntity user = userMapper.selectByUsername(username);
        if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
            throw new AuthenticationException("用户名或密码错误");
        }
        return user;
    }
}